from PyQt5.QtWidgets import QMainWindow,QApplication
from ui_1 import Ui_MainWindow
import matplotlib,mplcursors
matplotlib.use("Qt5Agg")  # 声明使用pyqt5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg  # pyqt5的画布
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from PyQt5 import QtCore, QtGui, QtWidgets
import  sys,openpyxl,pandas
from datetime import datetime,timedelta
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtCore import Qt


###读取案子的schedule, 案子为PDDTS下载下来的excel里面的所有案子
schedule_dict = {}
schedule_excel = openpyxl.load_workbook(r'C:\schedule.xlsx')
schedule_sheet = schedule_excel['Sheet1']
all_rows = schedule_sheet.max_row  # 获取最大行数
for row in range(1, all_rows + 1):
    schedule_dict.update({schedule_sheet[f'A{row}'].value: schedule_sheet[f'B{row}'].value})  # 更新字典
schedule_excel.close()
###读取案子的schedule, 案子为PDDTS下载下来的excel里面的所有案子



#创建一个画布类，并把画布放到FigureCanvasQTAgg, 固定用法
class MyMatplotlibFigure(FigureCanvasQTAgg):
    def __init__(self, width, heigh):
        plt.rcParams['font.sans-serif'] = ['SimHei']#防止中文乱码
        # 创建一个Figure,该Figure为matplotlib下的Figure，不是matplotlib.pyplot下面的Figure
        self.figs = Figure(figsize=(width, heigh))#2种方法都可以设置大小，Figure是个类，这里也相当于实例化
        #self.figs=plt.figure(figsize=(width, heigh))#2种方法都可以设置大小
        super().__init__(self.figs)  # 继承父类初始化，，这里说明FigureCanvasQTAgg这个类的初始化函数里肯定要传一个参数列如def __init__(self,name):
        #FigureCanvasQTAgg.__init__(self,self.figs) 也可以用这种显示继承方法
        self.axes = self.figs.add_subplot(111)  # 添加绘图区，1行1列就行了
        self.axes.axis('off')#隐藏最开始的默认坐标和元素
#创建一个画布类，并把画布放到FigureCanvasQTAgg, 固定用法



class MainDialogImgBW(QMainWindow,Ui_MainWindow):
    #逻辑UI分离固定用法
    def __init__(self):
        super().__init__()
        self.setupUi(self)
    #逻辑UI分离固定用法
        self.annotations_list = []#用于存储所有的annotate对象
        self.dt_zero_time = pandas.to_datetime("today").normalize()## 获取当前日期（时间归零）# 输出：2025-05-19 00:00:00，为了后面给当日日期备注对应的进度
        #读取excel数据给PYQT UI显示
        self.cursors = []#为后面创建的cursors加进来做准备，然后点view的时候清除之前创建的所有cursor
        df = pandas.read_excel(r'C:\issue_data.xlsx')
        release=df['Release'].drop_duplicates().unique()#unique去重复后再在PYQT页面显示供选择
        self.listWidget.addItems(release)
        component = df['Component'].drop_duplicates().unique()
        self.listWidget_2.addItems(component)
        requested_Priority = df['Requested Priority'].drop_duplicates().unique()
        self.listWidget_3.addItems(requested_Priority)
        # 读取excel数据给PYQT UI显示

        #这里是实现选择的逻辑关键，利用4个列表完全等长, 并且一一对应,  4个列表的list【0】刚好是excel 第一行的所需数据， list[1]第二行这样子
        self.release_list=df['Release'].tolist()#这里需要重复来供后面匹配条件选择,tolist转为列表
        self.componet_list=df['Component'].tolist()
        self.date_created = df['Date Created'].tolist() #2024-11-12 01:20:51，字符串格式
        self.date_created_list=[]
        for date in self.date_created:
            self.date_created_list.append(datetime.strptime(date[:-9], '%Y-%m-%d'))#去掉字符串后9位的时间，并且转为时间格式，方便比较大小[2025-03-10 00:00:00,2025-03-11 00:00:00]
        self.Requested_Priority_list = df['Requested Priority'].tolist()
        # 这里是实现选择的逻辑关键，利用4个列表完全等长, 并且一一对应,  4个列表的list【0】刚好是excel 第一行的所需数据， list[1]第二行这样子

        self.issue = MyMatplotlibFigure(0, 20)#调用上面的类，这里是受布局影响，宽度实际受布局影响，自动变最宽
        self.verticalLayout.addWidget(self.issue)#把画布类布局理解为控件加到PYQT5页面中，这里目前我了解到是是必须有布局才能加，这里画布也拥有了自动布局，自动缩放
        self.pushButton_7.clicked.connect(self.view)
        self.pushButton.clicked.connect(self.clear_project)
        self.pushButton_9.clicked.connect(self.select_all_project)
        self.pushButton_2.clicked.connect(self.clear_component)
        self.pushButton_8.clicked.connect(self.select_all_component)
        self.pushButton_3.clicked.connect(self.clear_level)
        self.pushButton_10.clicked.connect(self.select_all_level)
        self.pushButton_5.clicked.connect(self.compare)
        self.pushButton_6.clicked.connect(self.reset)
    def reset(self):
        self.listWidget.clearSelection()
        self.listWidget_2.clearSelection()
        self.listWidget_3.clearSelection()
        try:
            if hasattr(self, 'cursors'):  # 检查对象是否有self.cursors属性，如果有进行下一步，这里初始化有设置这个属性
                for each_cur in self.cursors:
                    each_cur.remove()  # 移除旧的每一个cursor，不移除的话上一个图形显示的坐标黄框提示依旧还在，多次点view就会有旧的，第一次点没有。没有就会报错，所以用try，第二次点就会清掉之前的
                    del each_cur
        except:
            pass
        self.issue.figs.suptitle("")
        self.issue.axes.cla()  #
        self.issue.axes.axis('off')
        self.issue.figs.canvas.draw()#重会画布
        self.issue.figs.canvas.flush_events()

        # 上面有点奇怪，如果我直接点击view，再reset，不能清除画布，必须加显示self.issue.figs.canvas.draw()#重会画布才能清除，，点了view再随便点一个坐标显示值后，再reset，不用加显示draw都可以清除画布
        #为了保险，以后都加上draw()吧显示，这是deepseek回答的可能的原因

        #当您调用，                                         这是deepseek回答的可能的原因
        # self.issue.axes.cla()
        # 后，虽然清除了绘图区，但没有主动刷新画布，导致界面未更新。
        # 点击坐标点后，mplcursors
        # 的交互事件间接触发了画布刷新，使得后续的
        # reset
        # 能正常显示清除效果
    def clear_project(self):
        self.listWidget.clearSelection()
    def select_all_project(self):
        self.listWidget.selectAll()#仅清除选择状态，保留列表中的数据，clear()：删除列表中的所有数据（包括选择状态）
    def clear_component(self):
        self.listWidget_2.clearSelection()#仅清除选择状态，保留列表中的数据，clear()：删除列表中的所有数据（包括选择状态）
    def select_all_component(self):
        self.listWidget_2.selectAll()#仅清除选择状态，保留列表中的数据，clear()：删除列表中的所有数据（包括选择状态）
    def clear_level(self):
        self.listWidget_3.clearSelection()#仅清除选择状态，保留列表中的数据，clear()：删除列表中的所有数据（包括选择状态）
    def select_all_level(self):
        self.listWidget_3.selectAll()#仅清除选择状态，保留列表中的数据，clear()：删除列表中的所有数据（包括选择状态）
    def view(self):
        project_list=[]
        selected_projects = self.listWidget.selectedItems()#获取选中的project
        for item in selected_projects:
            project_list.append(item.text())#这样就知道project_list由哪些案子了

        schedule_list = []  # 将开始和结束时间包含在里面
        schedule=schedule_dict[project_list[0]]#只需拿列表中的一个案子去找到shcedule就行了，这里return 2023-01-1&2023-02-02，因为都是一样的，view button定义查看一个案子的曲线图
        schedule_1=schedule.split('&')#再转为列表[2023-01-1,2023-02-02],开始和结束时间，但是是字符串
        for x in schedule_1:
            schedule_list.append(datetime.strptime(x, '%Y-%m-%d'))#转为时间格式，方便比较大小[2025-03-10 00:00:00,2025-03-11 00:00:00],

        component_list_1=[]
        selected_components = self.listWidget_2.selectedItems()
        for item1 in selected_components:
            component_list_1.append(item1.text())

        level_list = []
        selected_level = self.listWidget_3.selectedItems()
        for item2 in selected_level:
            level_list.append(item2.text())

        delta = schedule_list[1]-schedule_list[0]# 截止时间减开始时间
        juli_days=delta.days#转化为整数相差多少天

        progress_dates = {}#项目百分比对应的时间日期字典
        for percent in range(0, 101, 1):
            # 计算当前百分比对应的天数
            days_offset = int(juli_days * percent / 100)#返回整数，如果0.36天取0，代表这个进度还是在当天，1.36取1，代表这个进度是在+1天过后的那天，等于总天数*2%,4%这样子
            # 计算具体日期比如是1号到3号，100%的时候juli是2天，乘出来也是2天，1号加2天就是到3号刚刚好
            current_date = schedule_list[0] + timedelta(days=days_offset)#计算加多少天过后的是哪一天
            progress_dates[f"{percent}%"] = current_date#{2%:2025-05-03 00:00:00}转为这种
        t = [f"{x}%" for x in range(0, 101, 1)]
        s = [0]
        #获得s列表的值

        for x in range(1, 101, 1):#y要找到1%到100% 对应的的时间点以及issue 数量
            issue_num = 0
            enddate=progress_dates[f'{x}%']# 第一次返回1%对应的时间点
            for xx in range(0, len(self.date_created_list)):#利用前面4个列表等长，随便用1个列表取长度，再遍历小于等于2%对应的时间点以及PYQT5里筛选的条件来获得issue总数
                if  self.date_created_list[xx] <= enddate and self.release_list[xx] in project_list and self.componet_list[xx] in component_list_1 and self.Requested_Priority_list[xx] in level_list:# 判断每一行，如果时间小于等于，release 包含在UI里有选到的，等级包含在UI里有选到的
                    issue_num=issue_num+1# 就加1代表有符合条件
            s.append(issue_num)#最后遍历完了获得issue总数，4%的时候又重新遍历获得新的issue总数
        total_issue_number = 0  # 后面的issue numb只是算出了根据条件筛选的总数，这里需要一个这个案子的总数，方便后面计算issue占总的百分比
        for xxx in range(0, len(self.date_created_list)):
            if  self.release_list[xxx] in project_list:
                total_issue_number=total_issue_number+1
        # 获得s列表的值


        self.issue.axes.cla()# 清除绘图区，访问MyMatplotlibFigure类的axes变量
        self.issue.axes.spines['top'].set_visible(False)  # 顶边界不可见
        self.issue.axes.spines['right'].set_visible(False)  # 右边界不可见
        # 启用 mplcursors，鼠标悬停时显示数值
        line= self.issue.axes.plot(t, s, 'o-', linewidth=0.8,markersize=2,label=project_list[0])  # o-r圆点,横线连接，红色，linewidth是折线的宽度，这里就直接画图了，不需要在plt.show，# 返回 line 对象用于 mplcursors,markersize是设置圆点标记的大小，默认是6
        try:
            if hasattr(self, 'cursors'):#检查对象是否有self.cursors属性，如果有进行下一步，这里初始化有设置这个属性
                for each_cur in self.cursors:
                    each_cur.remove()  # 移除旧的每一个cursor，不移除的话上一个图形显示的坐标黄框提示依旧还在，多次点view就会有旧的，第一次点没有。没有就会报错，所以用try，第二次点就会清掉之前的
                    del each_cur
        #if hasattr教学理解
        # class MyClass:
        #     def __init__(self):
        #         self.my_attribute = 42
        # obj = MyClass()
        # # 检查对象是否有某个属性
        # if hasattr(obj, 'my_attribute'):
        #     print("对象有 my_attribute 属性")
        #     print(f"值为: {obj.my_attribute}")
        # else:
        #     print("对象没有 my_attribute 属性")
        # if hasattr教学理解
        #总结，用户的问题是因为画布刷新后，旧的cursor提示未被清除。解决方法可能是在每次更新时销毁旧的cursor并创建新的，或者在更新时手动清除所有注释。 当画布刷新后，之前由 mplcursors 显示的坐标提示未消失，通常是因为 旧的事件监听未被清理 或 旧的注释对象未被移除。以下是解决方案：
        except:
            pass

        self.cursor = mplcursors.cursor(line, hover=True)#对应前面的line固定用法

        def on_hover(sel):
            x_value = int(sel.target[0])  # 获取x坐标值
            y_value = int(sel.target[1])  # 获取y坐标值
            enddate_2 = progress_dates[f"{x_value}%"]  # 得到当前坐标点的结束时间
            high = medium = emergency = low = 0
            for kk in range(0, len(self.date_created_list)):
                if (self.date_created_list[kk] <= enddate_2 and self.release_list[kk] in project_list and self.componet_list[kk] in component_list_1 and self.Requested_Priority_list[kk] in level_list):
                    if self.Requested_Priority_list[kk] == 'Low':
                        low += 1
                    elif self.Requested_Priority_list[kk] == 'High':
                        high += 1
                    elif self.Requested_Priority_list[kk] == 'Medium':
                        medium += 1
                    else:
                        emergency += 1
            current_pct = int(sel.target[1] / total_issue_number * 100)
            emergency_pct = int(emergency / total_issue_number * 100)
            high_pct = int(high / total_issue_number * 100)
            medium_pct = int(medium / total_issue_number * 100)
            low_pct = int(low / total_issue_number * 100)
            text = (
                f"Current Issue: {y_value:>4} ({current_pct:>3}%)\n"
                f"Emergency:     {emergency:>4} ({emergency_pct:>3}%)\n"
                f"High:          {high:>4} ({high_pct:>3}%)\n"
                f"Medium:        {medium:>4} ({medium_pct:>3}%)\n"
                f"Low:           {low:>4} ({low_pct:>3}%)"
            )
            sel.annotation.set_text(text)
        self.cursor.connect("add", on_hover)#和def  on_hover固定用法
        #self.cursor.connect("add", lambda sel: sel.annotation.set_text(f"Issue数:{int(sel.target[1])}"+' '+"总占比:"+f"{int(sel.target[1]/issue_num*100)}"+"%")) #对应前面的line固定用法，lambda sel: ... 相当于 def on_hover(sel): ... 的简化版，但只能写一行表达式。
        self.cursors.append(self.cursor)
        self.issue.figs.suptitle("Issue Trend")  # 设置标题，访问MyMatplotlibFigure类的figs变量
        self.issue.axes.set_yticks([0, 50, 100, 150, 200, 250, 300, 350, 400, 450])
        self.issue.axes.set_xticks(['0%', '10%','20%','30%', '40%','50%','60%', "70%",'80%' ,'90%', '100%'])
        self.issue.axes.grid(color = '0.7', linestyle = '--', linewidth = 0.5)#设置网格
        self.issue.axes.set_xlabel('Project Pogress')
        self.issue.axes.set_ylabel('Issue Number')

       # #获取本地计算机时间，如果当前时间在schedule内则显示对应的进度和数量，不在就不显示
       #  for percent3, date3 in progress_dates.items():
       #      if date3 == self.dt_zero_time:#如果当日日期在字典里有对应的
       #          current_percent = percent3#这里date3可能有重复，比如2%，4%都对应同一个时间取最后一个时间，取大的百分比 比较好,不取大的就可以直接break
       #  try:
       #      if 'current_percent' in locals():#如果这个变量存在，代表有找到对应的值
       #          current_index = t.index(current_percent)#两个列表等长，进度对应总的issue数量，获取进度的列表index下标，再用下标找到issue的对应的值
       #          current_issues = s[current_index]
       #          ann=self.issue.axes.annotate(
       #              f'Today: {current_percent}\nIssues: {current_issues}',# 要显示的文本
       #              xy=(current_percent,current_issues),  # 箭头指向的坐标点，这里设置为在最后显示
       #              xytext=(20, 40),  # 文本位置（偏移量）
       #              textcoords='offset points',#定义标注文本位置 (xytext) 的坐标系。'offset points' 表示 xytext=(20, 40) 是相对于 xy 点的像素偏移量：(20, 40) 表示文本位于 xy 点右侧 20 像素、上方 40 像素处。
       #              arrowprops=dict(         # 箭头的属性（样式、颜色等）
       #                  arrowstyle="->",  # 箭头样式
       #                  connectionstyle="arc3,rad=0.3",  # 箭头弯曲程度，"arc3" 表示使用三次贝塞尔曲线绘制连接线（默认是直线，rad=0.3 控制曲线的弯曲程度（半径）正值：箭头向右弯曲（顺时针方向）负值：箭头向左弯曲（逆时针方向
       #                  color='red'
       #                             ),
       #              bbox=dict(          # 文本框的属性（背景色、边框等）
       #                  boxstyle='round,pad=0.5',  # 圆角文本框
       #                  fc='lightyellow',  # 背景色
       #                  alpha=0.8  # 透明度
       #                       ),
       #              fontsize=10,
       #              #color='red',设置字体颜色
       #              # fontdict={设置字体颜色
       #              #     'size': 10,
       #              #     'color': 'green',  # 文字颜色
       #              #     'family': 'serif',  # 字体
       #              #     'weight': 'bold'  # 粗细
       #              # }
       #          )
       #          self.annotations_list.append(ann)
       #      elif schedule_list[0] <= self.dt_zero_time and self.dt_zero_time <= schedule_list[1]:# 在schedule内 但是字典里没有，比如你这时间点可能对应的百分比不在字典内不在横坐标内:重新算进度和issue
       #
       #          delta1=self.dt_zero_time - schedule_list[0]  # 当前时间减开始时间
       #          juli_days_1 = delta1.days  # 转化为整数相差多少天
       #          jindu=round((juli_days_1+1)/(juli_days+1)*100)#计算当前进度，这个和之前的算法有点区别，比如时间1号到10号，今天5号，减出来差4天，实际百分比是5天除以总的天数juli_days+1，juliday是之前算出来的
       #          issue_num_1 = 0
       #          for yy in range(0,len(self.date_created_list)):  # 利用前面4个列表等长，随便用1个列表取长度，再遍历小于等于2%对应的时间点以及PYQT5里筛选的条件来获得issue总数
       #              if self.date_created_list[yy] <= self.dt_zero_time and self.release_list[yy] in project_list and self.componet_list[yy] in component_list_1 and self.Requested_Priority_list[yy] in level_list:  # 判断每一行，如果时间小于等于，release 包含在UI里有选到的，等级包含在UI里有选到的
       #                  issue_num_1 = issue_num_1 + 1  # 就加1代表有符合条件
       #          ann=self.issue.axes.annotate(
       #              f'Today: {jindu}%\nIssues: {issue_num_1}',  # 要显示的文本
       #              xy=(t[-1], s[-1]),  # 箭头指向的坐标点，这里设置为在最后显示
       #              xytext=(20,40),  # 文本位置（偏移量）
       #              textcoords='offset points',
       #              # 定义标注文本位置 (xytext) 的坐标系。'offset points' 表示 xytext=(20, 40) 是相对于 xy 点的像素偏移量：(20, 40) 表示文本位于 xy 点右侧 20 像素、上方 40 像素处。
       #              arrowprops=dict(  # 箭头的属性（样式、颜色等）
       #                  arrowstyle="->",  # 箭头样式
       #                  connectionstyle="arc3,rad=0.3",
       #                  # 箭头弯曲程度，"arc3" 表示使用三次贝塞尔曲线绘制连接线（默认是直线，rad=0.3 控制曲线的弯曲程度（半径）正值：箭头向右弯曲（顺时针方向）负值：箭头向左弯曲（逆时针方向
       #                  color='red'
       #              ),
       #              # bbox=dict(  # 文本框的属性（背景色、边框等）
       #              #     boxstyle='round,pad=0.5',  # 圆角文本框
       #              #     fc='lightyellow',  # 背景色
       #              #     alpha=0.8  # 透明度
       #              # ),
       #              fontsize=10,
       #              # color='red',设置字体颜色
       #              # fontdict={设置字体颜色
       #              #     'size': 10,
       #              #     'color': 'green',  # 文字颜色
       #              #     'family': 'serif',  # 字体
       #              #     'weight': 'bold'  # 粗细
       #              # }
       #          )
       #          self.annotations_list.append(ann)
       #      else:
       #          pass
       #  except:
       #      pass
        self.issue.axes.legend(loc='best', prop={'size': 10},  frameon=False)#设置图列abby-AMD，图例是根据lable标签生成，line, =self.issue.axes.plot(t, s, 'o-r', linewidth=0.8,markersize=2,label="Abby-AMD")
        self.issue.figs.canvas.draw()  # 这里注意是画布重绘，self.figs.canvas
        self.issue.figs.canvas.flush_events()  # 画布刷新self.figs.canvas
    def compare(self):
        for ann in self.annotations_list:#清除之前生成的坐标点进度issue说明，比较的时候不需要！！！！！！！！！！！！！
            ann.remove()
        self.annotations_list.clear()

        project_list=[]
        selected_projects = self.listWidget.selectedItems()#获取选中的project
        for item in selected_projects:
            project_list.append(item.text())#这样就知道project_list由哪些案子了

        schedule_list = []  # 将开始和结束时间包含在里面
        schedule=schedule_dict[project_list[0]]#只需拿列表中的一个案子去找到shcedule就行了，这里return 2023-01-1&2023-02-02，因为都是一样的，view button定义查看一个案子的曲线图
        schedule_1=schedule.split('&')#再转为列表[2023-01-1,2023-02-02],开始和结束时间，但是是字符串
        for x in schedule_1:
            schedule_list.append(datetime.strptime(x, '%Y-%m-%d'))#转为时间格式，方便比较大小[2025-03-10 00:00:00,2025-03-11 00:00:00],

        component_list_1=[]
        selected_components = self.listWidget_2.selectedItems()
        for item1 in selected_components:
            component_list_1.append(item1.text())

        level_list = []
        selected_level = self.listWidget_3.selectedItems()
        for item2 in selected_level:
            level_list.append(item2.text())

        delta = schedule_list[1]-schedule_list[0]# 截止时间减开始时间
        juli_days=delta.days#转化为整数相差多少天

        progress_dates = {}#项目百分比对应的时间日期字典
        for percent in range(0, 101, 1):
            # 计算当前百分比对应的天数
            days_offset = int(juli_days * percent / 100)#返回整数，如果0.36天取0，代表这个进度还是在当天，1.36取1，代表这个进度是在+1天过后的那天，等于总天数*2%,4%这样子
            # 计算具体日期比如是1号到3号，100%的时候juli是2天，乘出来也是2天，1号加2天就是到3号刚刚好
            current_date = schedule_list[0] + timedelta(days=days_offset)#计算加多少天过后的是哪一天
            progress_dates[f"{percent}%"] = current_date#{2%:2025-05-03 00:00:00}转为这种

        t = [f"{x}%" for x in range(0, 101, 1)]
        s = [0]

        #获得s列表的值
        for x in range(1, 101, 1):#y要找到2%到100% 对应的的时间点以及issue 数量
            issue_num = 0
            enddate=progress_dates[f'{x}%']# 第一次返回2%对应的时间点
            for xx in range(0, len(self.date_created_list)):#利用前面4个列表等长，随便用1个列表取长度，再遍历小于等于2%对应的时间点以及PYQT5里筛选的条件来获得issue总数
                if  self.date_created_list[xx] <= enddate and self.release_list[xx] in project_list and self.componet_list[xx] in component_list_1 and self.Requested_Priority_list[xx] in level_list:# 判断每一行，如果时间小于等于，release 包含在UI里有选到的，等级包含在UI里有选到的
                    issue_num=issue_num+1# 就加1代表有符合条件
            s.append(issue_num)#最后遍历完了获得issue总数，4%的时候又重新遍历获得新的issue总数
        total_issue_number1 = 0  # 后面的issue numb只是算出了根据条件筛选的总数，这里需要一个这个案子的总数，方便后面计算issue占总的百分比
        for yyy in range(0, len(self.date_created_list)):
            if self.release_list[yyy] in project_list:
                total_issue_number1 = total_issue_number1 + 1
        # 获得s列表的值

        line=self.issue.axes.plot(t, s, 'o-', linewidth=0.8,markersize=2,label=project_list[0])  # o-r圆点,红色，linewidth是折线的宽度，这里就直接画图了，不需要在plt.show，# 返回 line 对象用于 mplcursors,markersize是设置圆点标记的大小，默认是6
        self.cursor = mplcursors.cursor(line, hover=True)#对应前面的line固定用法

        def on_hover(sel):
            x_value = int(sel.target[0])  # 获取x坐标值
            y_value = int(sel.target[1])  # 获取y坐标值
            enddate_2 = progress_dates[f"{x_value}%"]  # 得到当前坐标点的结束时间
            high = medium = emergency = low = 0
            for kk in range(0, len(self.date_created_list)):
                if (self.date_created_list[kk] <= enddate_2 and self.release_list[kk] in project_list and
                        self.componet_list[kk] in component_list_1 and self.Requested_Priority_list[kk] in level_list):
                    if self.Requested_Priority_list[kk] == 'Low':
                        low += 1
                    elif self.Requested_Priority_list[kk] == 'High':
                        high += 1
                    elif self.Requested_Priority_list[kk] == 'Medium':
                        medium += 1
                    else:
                        emergency += 1
            current_pct = int(sel.target[1] / total_issue_number1 * 100)
            emergency_pct = int(emergency / total_issue_number1 * 100)
            high_pct = int(high / total_issue_number1 * 100)
            medium_pct = int(medium / total_issue_number1 * 100)
            low_pct = int(low / total_issue_number1 * 100)
            text = (
                f"Current Issue: {y_value:>4} ({current_pct:>3}%)\n"
                f"Emergency:     {emergency:>4} ({emergency_pct:>3}%)\n"
                f"High:          {high:>4} ({high_pct:>3}%)\n"
                f"Medium:        {medium:>4} ({medium_pct:>3}%)\n"
                f"Low:           {low:>4} ({low_pct:>3}%)"
            )
            sel.annotation.set_text(text)
        self.cursor.connect("add", on_hover)
        self.cursors.append(self.cursor)
        self.issue.figs.suptitle("Issue Trend")  # 设置标题，访问MyMatplotlibFigure类的figs变量
        self.issue.axes.set_yticks([0, 50, 100, 150, 200, 250, 300, 350, 400, 450])
        self.issue.axes.set_xticks(['0%', '10%','20%','30%', '40%','50%','60%', "70%",'80%' ,'90%', '100%'])
        self.issue.axes.grid(color='0.7',linestyle='--',linewidth=0.5)#设置网格
        self.issue.axes.set_xlabel('Project Pogress')
        self.issue.axes.set_ylabel('Issue Number')
        self.issue.axes.legend(loc='best',  prop={'size': 10},  frameon=False)#设置图列abby-AMD，图例是根据lable标签生成，line, =self.issue.axes.plot(t, s, 'o-r', linewidth=0.8,markersize=2,label="Abby-AMD")
        self.issue.figs.canvas.draw()  # 这里注意是画布重绘，self.figs.canvas
        self.issue.figs.canvas.flush_events()  # 画布刷新self.figs.canvas

if __name__ == "__main__":
    QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)  # 不管在开发的机器上窗口设置多大，用户机器使用的时候窗口根据用户设备尺寸大小自动调整窗口大小使其居中
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)#自适应分辨
    app = QtWidgets.QApplication(sys.argv)
    main = MainDialogImgBW()
    main.show()
    sys.exit(app.exec_())


